package com.siyu.model.dispatch.model.common.singlersvr;

import com.alibaba.fastjson.JSONObject;
import com.siyu.model.dispatch.algorithm.ConventionalSingleReservoir;
import com.siyu.model.dispatch.algorithm.MuskingenMethod;
import com.siyu.model.dispatch.dto.DispatchDto;
import com.siyu.model.dispatch.io.*;
import com.siyu.model.dispatch.model.interfaces.Model;
import com.siyu.model.dispatch.utils.CommonUtils;
import org.apache.commons.io.FileUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.File;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

public class SingleRsvr implements Model {
    /*
     * 实例字段和构造器
     */
    protected Logger logger = LogManager.getLogger(this.getClass());
    private final String folderPath;

    /**
     * 有初始化参数文件路径的构造器
     *
     * @param path
     */
    public SingleRsvr(String path) {
        this.folderPath = path;
    }

    /**
     * 模型初始化
     *
     * @return 模型初始化参数对象(BainiheInput)
     */
    public FloodDispatchInput initModel(DispatchDto dispatchDto) throws Exception {
        FloodDispatchInput input = new FloodDispatchInput();
        SingleReservoir singleReservoir = new SingleReservoir(folderPath);

        /*
         * SingleDamInput 初始化过程
         */
        // todo 读取第1座水库的数据，现在是从txt，后面改为数据库读取
        SingleDamInput singleDamInput1 = singleReservoir.getSingleDamInput(dispatchDto);

        /*
         * 将单个水库或闸坝输入信息（SingleDamInput、SingleSluiceInput） 存入 总输入类 input（FloodDispatchInput）
         * List 中 3 个水库数据依次顺序为 singleDamInput1、singleDamInput2、singleDamInput3
         */
        input.getDamList().add(singleDamInput1);

        return input;
    }

    /**
     * 模型计算
     *
     * @param input 模型初始化参数对象(BainiheInput)
     * @return 模型计算结果对象(BainiheResult)
     * @throws IOException
     */
    public FloodDispatchOutput calculate(FloodDispatchInput input) throws Exception {
        final String outputFileName = "ConventionalSchedulingResult.txt";
        FloodDispatchOutput output = new FloodDispatchOutput();

        /*
         * 向输出类中设置预定格式的 JSON 对象
         */
        List<JSONObject> dataList = new ArrayList<>();
        output.setJsonObject(CommonUtils.createJSONObject(dataList));

        // 马斯京根河道演算
        MuskingenMethod oneChannel = new MuskingenMethod();

        // 三坑水库、福源水库和芙蓉嶂 三座水库分别编号3、2、1，计算的时候从下往上算：1,2,3这个顺序
        SingleDamInput singleDamInput1 = input.getDamList().get(0);
        ConventionalSingleReservoir damRes1 = new ConventionalSingleReservoir(singleDamInput1, folderPath, "1", 123, 123, oneChannel);
        damRes1.calculate();
        SingleDamOutput singleDamOutput1 = damRes1.getSingleDamOutput();  // 获取单水库结果
        output.getDamList().add(singleDamOutput1);
        dataList.add(CommonUtils.addJSONObject(singleDamInput1, singleDamOutput1));
        // TODO：输入 txt 看结果，后面可以删除
//        damRes1.OutputResults(folderPath + File.separator + "1" + File.separator + outputFileName);

        // 马斯京根河道演算
        double[] tempQ1 = damRes1.getTempQ();  //芙蓉嶂水库1

        double[] tempChuKouQ1 = new double[damRes1.getOptimalLine_Qrelease()[0].length];

        double[] Qrelease0 = damRes1.getOptimalLine_Qrelease()[0];  // 各时段下泄流量
        int length = Qrelease0.length;


        // 输出马斯京根演算后的鸦岗流量
        List<Double> tempQ = new ArrayList<>();
        for (int j = 0; j < tempQ1.length; j++) {
            tempQ.add(tempQ1[j]  + tempChuKouQ1[j]);
        }
        ChukouResult Chukou = new ChukouResult();
        Chukou.setQ(tempQ);
        output.setChukou(Chukou);


        //计算总的调度建议
        String suggestion =
                damRes1.getSingleDamOutput().getSuggestion() + "\n" ;

        output.setCollectSuggestion(suggestion);

        logger.info("计算结束");

        return output;
    }

}
